package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.constant.MonitorCommonMap;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.dao.DefinitionMetricTypeDao;
import com.bsg.upm.dao.MonitorEventDao;
import com.bsg.upm.entity.ClusterEntity;
import com.bsg.upm.entity.HostEntity;
import com.bsg.upm.entity.MonitorEventEntity;
import com.bsg.upm.entity.ServEntity;
import com.bsg.upm.entity.UnitEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

@Service
public class MonitorEventService extends BaseService {
	@Resource
	MonitorEventDao monitorEventDao;

	@Resource
	DefinitionMetricTypeDao definitionMetricTypeDao;

	public void handleTask(String siteId) {
		try {
			List<String> sender = new ArrayList<String>();

			JSONArray events = getRawFromHorus(siteId);
			if (events == null || events.isEmpty()) {
				return;
			}

			List<MonitorEventEntity> monitorEventEntities = monitorEventDao.list(null);
			List<HostEntity> hostEntities = hostDao.list(null);

			for (int index = 0; index < events.size(); index++) {
				JSONObject event = (JSONObject) events.get(index);

				if (monitorEventEntities != null) {
					boolean exist = false;

					for (MonitorEventEntity monitorEventEntity : monitorEventEntities) {
						if (monitorEventEntity.getId().equals(event.getString("id"))) {
							sender.add(event.getString("id"));
							exist = true;
							break;
						}
					}

					if (exist) {
						continue;
					}

				}

				MonitorEventEntity monitorEventEntity = buildEntityByObj(event, hostEntities);
				if (monitorEventEntity == null) {		
					logger.warn(event.getString("id") + "buildEntityByObj fail.");
					sender.add(event.getString("id"));
					continue;
				}

				if (saveToDB(monitorEventEntity)) {
					sender.add(event.getString("id"));
				}else {
					
					logger.warn(event.getString("id")+ ":monitorEventEntity sateToDb fail");
					sender.add(event.getString("id"));
				}

				if (sender.size() >= 5) {
					sendDisposedToHorus(siteId, sender);
					sender.clear();
				}

			}

			if (!sender.isEmpty()) {
				sendDisposedToHorus(siteId, sender);
			}

		} catch (Exception e) {
			logger.error("MonitorEventService:handle  fail:" + e);
		}

	}

	public RespJson getShowEvent(Map<String, Object> paramMap) throws APIException {
		try {
			// handleTask("c3ee1f1846f84e9cb199173b332572e8");

			JSONArray ret = new JSONArray();

			List<MonitorEventEntity> eventEntities = monitorEventDao.listEvent(paramMap);
			if (eventEntities == null) {
				return RespJsonFactory.buildOK(ret);
			}

			List<ClusterEntity> clusters = clusterDao.listWithoutAssociation();
			List<ServEntity> servs = servDao.listWithoutAssociation();
			List<HostEntity> hosts = hostDao.listWithoutAssociation();

			for (MonitorEventEntity eventEntity : eventEntities) {
				JSONObject object = new JSONObject();
				object.put("name", eventEntity.getMetric());
				object.put("value", eventEntity.getValue());
				object.put("level", eventEntity.getLevel());
				object.put("create_time", eventEntity.getCreateTimestamp());
				object.put("owner", eventEntity.getOwner());

				boolean servFind = false;
				object.put("serv_name", null);
				if (servs != null && eventEntity.getServId() != null) {
					for (ServEntity serv : servs) {
						if (serv.getId().equals(eventEntity.getServId())) {
							object.put("serv_name", serv.getServName());
							servFind=true;
							break;
						}
					}
				}

				if (!servFind && !eventEntity.getObjType().equals(MonitorCommonMap.HOST_TYPE)) {
					continue;
				}

				boolean hostFind = false;
				object.put("host_name", null);
				if (hosts != null) {

					for (HostEntity host : hosts) {
						if (host.getRelateId() == null) {
							continue;
						}
						if (host.getRelateId().equals(eventEntity.getHostRelateId())) {
							object.put("host_name", host.getName());
							hostFind=true;
							break;
						}
					}
				}

				if (!hostFind && eventEntity.getObjType().equals(MonitorCommonMap.HOST_TYPE)) {
					continue;
				}

				object.put("cluster_name", null);
				if (clusters != null) {
					for (ClusterEntity cluster : clusters) {
						if (cluster.getId().equals(eventEntity.getClusterId())) {
							object.put("cluster_name", cluster.getName());
							break;
						}
					}
				}

				ret.add(object);

			}

			return RespJsonFactory.buildOK(ret);

		} catch (Exception e) {
			logger.error("getShowEvent fail:", e);
			throw new APIException("getShowEvent fail:" + e.getMessage());
		}

	}

	private Boolean saveToDB(MonitorEventEntity monitorEventEntity) {

		try {
			monitorEventDao.save(monitorEventEntity);
			return true;
		} catch (Exception e) {
			logger.error("monitorEventDao.save  fail:" + e);
		}

		return false;

	}

	private MonitorEventEntity buildEntityByObj(JSONObject obj, List<HostEntity> hostEntities) {
		MonitorEventEntity monitorEventEntity = new MonitorEventEntity();

		monitorEventEntity.setId(obj.getString("id"));
		monitorEventEntity.setLevel(obj.getString("level"));
		monitorEventEntity.setValue(obj.getString("value"));
		monitorEventEntity.setMetric(obj.getString("metric"));

		monitorEventEntity.setSend(false);
		monitorEventEntity.setAlarm(obj.getBoolean("alarm"));

		Long timpstamp = obj.getLong("createstamp");
		Date data = new Date(timpstamp * 1000);
		monitorEventEntity.setCreateTimestamp(data);

		String hostRelateId = obj.getString("obj_host_name");
		monitorEventEntity.setHostRelateId(hostRelateId);

		if (hostEntities != null) {
			boolean find = false;
			for (HostEntity hostEntity : hostEntities) {
				if (hostEntity.getRelateId().equals(hostRelateId)) {
					monitorEventEntity.setClusterId(hostEntity.getCluster().getId());
					monitorEventEntity.setAreaId(hostEntity.getCluster().getArea().getId());
					monitorEventEntity.setSiteId(hostEntity.getCluster().getArea().getSite().getId());
					monitorEventEntity.setOwner(hostEntity.getCreateUserLoginName());
					find = true;
					break;
				}
				if (!find) {
					return null;
				}
			}
		} else {
			return null;
		}

		String objConainterName = obj.getString("obj_container_name");
		String objName = obj.getString("obj_name");
		String objType = obj.getString("obj_type");

		monitorEventEntity.setObj(objName);

		switch (objType) {
		case MonitorCommonMap.HOST_TYPE:
			monitorEventEntity.setObjType(objType);
			break;

		// 单元 容器
		default:
			UnitEntity unitEntity = null;

			if (objType.equals(MonitorCommonMap.CONTAINER_TYPE)) {
				unitEntity = unitDao.getByRelateName(objConainterName);
			} else {
				unitEntity = unitDao.getByRelateId(objName);
			}

			if (unitEntity == null) {
				logger.warn(objConainterName + " or " + objName + ":dont't find unitEntity");
				return null;
			}

			String servType = unitEntity.getSubServ().getSubOrder().getDefinitionSubServ().getName();

			monitorEventEntity.setObjType(servType);

			String owner = unitEntity.getSubServ().getServ().getOrder().getOwner();
			monitorEventEntity.setOwner(owner);

			monitorEventEntity.setServId(unitEntity.getSubServ().getServ().getId());

			String businessSubSystemId = unitEntity.getSubServ().getServ().getOrder().getBusinessSubSystem().getId();

			monitorEventEntity.setSubSystemId(businessSubSystemId);
			String businessSystemId = unitEntity.getSubServ().getServ().getOrder().getBusinessSubSystem()
					.getBusinessSystem().getId();

			monitorEventEntity.setSystemId(businessSystemId);

			break;
		}

		return monitorEventEntity;
	}

	private JSONArray getRawFromHorus(String siteId) {

		String urlPattern = "/{0}/events?send=false";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);
		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("sendDgetRawFromHorus  fail:" + httpRespJson);
			return null;
		}

		return (JSONArray) httpRespJson.getData();
	}

	private void sendDisposedToHorus(String siteId, List<String> eventIds) {
		JSONObject ret = new JSONObject();
		ret.put("event_id", eventIds);

		String urlPattern = "/{0}/event";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);
		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, ret.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("sendDisposedToHorus fail:" + httpRespJson);
		}
	}

	private boolean isHttp2XX(int status) {
		if (status != HttpStatus.SC_OK || status != HttpStatus.SC_CREATED) {
			return false;
		}
		return true;
	}

}
